//
//  WeiXinCell.m
//  WeixinDeom
//
//  Created by iHope on 13-12-31.
//  Copyright (c) 2013年 任海丽. All rights reserved.
//

#import "ChatCell.h"
#import "ENTBoost.h"
#import "ChatImage.h"
#import "RunningCache.h"
#import <CoreText/CoreText.h>

#define CONTENT_HORI_SAPCE 20.0f
#define CONTENT_VERT_SAPCE 10.0f
#define CONTENT_MAX_WIDTH 150.0f
#define CONTENT_MAX_HEIGHT 10000.0f

#define IOS7 [[[UIDevice currentDevice]systemVersion] floatValue] >= 7.0

//使用完后销毁对象
static void RunDelegateDeallocCallback( void* refCon ){
    CFRelease(refCon);
}

//获取图片显示高度
static CGFloat RunDelegateGetAscentCallback( void *refCon ){
    NSString *tag = (__bridge NSString *)refCon;
    ChatImage* chatImage = [[RunningCache sharedCache] chatImageForTag:tag];
    
    if(chatImage)
        return chatImage.scaleSize.height;
    else
        return 0.0;
    //return [UIImage imageNamed:imageName].size.height;
    //return 50;
}

//获取图片显示下降高度
static CGFloat RunDelegateGetDescentCallback(void *refCon){
    NSString *tag = (__bridge NSString *)refCon;
    ChatImage* chatImage = [[RunningCache sharedCache] chatImageForTag:tag];
    
    if(chatImage) {
        //NSLog(@"descender = %f", fabsf(chatImage.descender));
        return fabsf(chatImage.descender);
    }
    else
        return 0.0;

    //return -[UIFont boldSystemFontOfSize:20].descender;
}

//获取图片显示宽度
static CGFloat RunDelegateGetWidthCallback(void *refCon){
    NSString *tag = (__bridge NSString *)refCon;
    ChatImage* chatImage = [[RunningCache sharedCache] chatImageForTag:tag];
    
    if(chatImage)
        return chatImage.scaleSize.width;
    else
        return 0.0;
    //return [UIImage imageNamed:imageName].size.width;
    //return 50;
}

@implementation ChatCell

- (void)insertImage:(UIImage*)image imageType:(CHAT_IMAGE_TYPE)imageType attributedString:(NSMutableAttributedString*)attributedString font:(UIFont*)uiFont usingScaleSize:(CGSize)scaleSize forTag:(NSString*)tag
{
    RunningCache* cache = [RunningCache sharedCache];
    
    //获取全局单实例锁对象
    static dispatch_once_t pred = 0;
    __strong static NSString* lock = nil;
    dispatch_once(&pred, ^{
        lock = @"LOCK";
    });

    //在缓存中查找图片资源，如果不存在则进行加载
    @synchronized(lock) {
        ChatImage* chatImage = [cache chatImageForTag:tag];
        if(!chatImage) {
            if(scaleSize.width == CGSizeZero.width && scaleSize.height == CGSizeZero.height) {
                chatImage = [[ChatImage alloc] initWithImage:image forTag:tag];
            } else {
                chatImage = [[ChatImage alloc] initWithImage:image UsingScaleSize:scaleSize forTag:tag];
            }
            [cache addChatImage:chatImage];
        }
        chatImage.descender = uiFont.descender;
        chatImage.imageType = imageType;
    }
    
    //为图片设置CTRunDelegate,delegate决定留给图片的空间大小
    CTRunDelegateCallbacks imageCallbacks;
    imageCallbacks.version      = kCTRunDelegateVersion1;
    imageCallbacks.dealloc      = RunDelegateDeallocCallback;
    imageCallbacks.getAscent    = RunDelegateGetAscentCallback;
    imageCallbacks.getDescent   = RunDelegateGetDescentCallback;
    imageCallbacks.getWidth     = RunDelegateGetWidthCallback;
    CTRunDelegateRef runDelegate = CTRunDelegateCreate(&imageCallbacks, (__bridge_retained void *)(tag));
    
    NSMutableAttributedString *imageAttributedString = [[NSMutableAttributedString alloc] initWithString:@" "];//空格用于给图片留位置
    [imageAttributedString addAttribute:(NSString *)kCTRunDelegateAttributeName value:(__bridge id)runDelegate range:NSMakeRange(0, 1)];
    CFRelease(runDelegate);
    
    //设置图片唯一标识属性
    [imageAttributedString addAttribute:CHAT_IMAGE_TAG_NAME value:tag range:NSMakeRange(0, 1)];
    
    //追加属性字符串
    [attributedString appendAttributedString:imageAttributedString];
}

/*计算内容的显示区域大小
 * @param ctFramesetter
 * @param size 最大区域范围
 * @return 显示区域大小
 */
- (CGSize)suggestSizeFrameSizeWithFramesetter:(CTFramesetterRef)ctFramesetter size:(CGSize)size
{
    //CGSize suggestSize =CTFramesetterSuggestFrameSizeWithConstraints(ctFramesetter,CFRangeMake(0, 0), NULL, maxSize, NULL); //该方法有BUG，别用
    
    //创建绘图路径并把设置矩形参数
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, CGRectMake(0.0, 0.0, size.width, size.height));
    
    CTFrameRef ctFrame = CTFramesetterCreateFrame(ctFramesetter, CFRangeMake(0, 0), path, NULL); //创建一个帧并在上下文执行绘制文本
    
    NSArray *lines = (__bridge NSArray *) CTFrameGetLines(ctFrame); //获取帧中所有行
    NSLog(@"line count = %i", lines.count);
    
    //获取各行的起始坐标
    CGPoint lineOrigins[lines.count];
    CTFrameGetLineOrigins(ctFrame, CFRangeMake(0, 0), lineOrigins);
    
    CGFloat ascent;
    CGFloat descent;
    CGFloat leading;
    CGFloat maxWidth = 0.0;
    CGFloat totalHeight = 0.0;
    int i =0;
    //循环每一行找出最大宽度及总高度
    for(i=0; i<lines.count; i++) {
        CTLineRef line = (__bridge CTLineRef)[lines objectAtIndex:i];
        double width = CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
        if(maxWidth < width)
            maxWidth = width;
        
        if(i == lines.count-1) { //最后一行
            totalHeight = size.height - lineOrigins[i].y + descent;
        }
    }
    
    CFRelease(ctFrame);
    CFRelease(path);
    
    return CGSizeMake(maxWidth, totalHeight);
}

- (void)setContent:(EBMessage*)message fromSelf:(BOOL)fromSelf
{
    UIView* bubbleView = [self viewWithTag:102];
    
    for (UIView *subView in bubbleView.subviews) {
        [subView removeFromSuperview];
    }
    
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] init]; //定义属性字符串
    UIFont* uiFont = [UIFont boldSystemFontOfSize:14]; //定义字体

    //获取富文本信息内容
    NSArray* chats = message.chats;
    [chats enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        EBChat* chatDot = obj;
        switch (chatDot.type) {
            case EB_CHAT_ENTITY_TEXT:
            {
                NSString* text = ((EBChatText*)chatDot).text;
                NSLog(@"[%lu]文本段:%@", (unsigned long)idx, text);
                //追加字符串
                [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:text]];
            }
                break;
            case EB_CHAT_ENTITY_RESOURCE:
            {
                EBChatResource* resDot = (EBChatResource*)chatDot;
                EBEmotion* expression = resDot.expression;
                NSLog(@"[%lu]资源(表情)段:resId = %llu, 文件路径 = %@", (unsigned long)idx, expression.resId, expression.dynamicFilepath);
                
                NSString* tag = [NSString stringWithFormat:@"expression_%llu", expression.resId];
                UIImage* image = [UIImage imageWithContentsOfFile:expression.dynamicFilepath];
                [self insertImage:image imageType:CHAT_IMAGE_TYPE_RESOURCE attributedString:attributedString font:uiFont usingScaleSize:CGSizeMake(24, 24) forTag:tag];
            }
                break;
            case EB_CHAT_ENTITY_IMAGE:
            {
                EBChatImage* imageDot = (EBChatImage*)chatDot;
                //NSData* imageData  = imageDot.data;
                UIImage* image = imageDot.image;
                CGSize size = image.size;
                NSLog(@"[%lu]图片段:大小%fX%f", (unsigned long)idx, size.width, size.height);
                
                NSString* tag = [NSString stringWithFormat:@"image_%@", image];
                [self insertImage:image imageType:CHAT_IMAGE_TYPE_COMMON attributedString:attributedString font:uiFont usingScaleSize:CGSizeZero forTag:tag];
            }
                break;
            case EB_CHAT_ENTITY_AUDIO:
            {
                EBChatAudio* audioDot = (EBChatAudio*)chatDot;
                NSLog(@"[%lu]语音段:长度(字节)%lu", (unsigned long)idx, (unsigned long)audioDot.data.length);
            }
                break;
        }
    }];
    NSLog(@"string length = %i", attributedString.length);
    
    //字体
    [attributedString addAttribute:(NSString *)kCTFontAttributeName value:(id)uiFont range:NSMakeRange(0, attributedString.length)];
//    //字间距
//    [attributedString addAttribute:(id)kCTKernAttributeName value:(id)[NSNumber numberWithFloat:0.0f] range:NSMakeRange(0, attributedString.length)];
    
    //设置换行模式和行间距
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;
//    CGFloat leading = uiFont.lineHeight - uiFont.ascender + fabsf(uiFont.descender);
//    NSLog(@"leading %f", leading);
    paragraphStyle.lineSpacing = 0;
    NSDictionary *attributes = @{NSParagraphStyleAttributeName:paragraphStyle};
    [attributedString addAttributes:attributes range:NSMakeRange(0, attributedString.length)];
    
    //格式化显示时间
    NSDateFormatter* fmt = [[NSDateFormatter alloc] init];
    fmt.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];
    
    NSDateComponents *componentsOfNow = [[NSCalendar currentCalendar] components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:[NSDate date]];
    NSDateComponents *componentsOfMsg = [[NSCalendar currentCalendar] components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:message.msgTime];
    if (componentsOfNow.year == componentsOfMsg.year && componentsOfNow.month == componentsOfMsg.month) { //同年同月
        if(componentsOfNow.day == componentsOfMsg.day) { //同日
            fmt.dateFormat = @"HH:mm";
        } else {
            fmt.dateFormat = @"MMMd日 EEE HH:mm";
        }
    } else {
        fmt.dateFormat = @"yyyy年MMMd日 HH:mm";
    }
    
    NSString* dateString = [fmt stringFromDate:message.msgTime];
    NSMutableAttributedString* timeAttrStr = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"\n%@", dateString]];
    [timeAttrStr addAttribute:(NSString *)kCTForegroundColorAttributeName value:(id)[UIColor grayColor].CGColor range:NSMakeRange(0, dateString.length+1)];
    [attributedString appendAttributedString:timeAttrStr];
    
    //创建消息显示视图
    [self prepareView:bubbleView attributedString:attributedString fromSelf:fromSelf];
    
//    [self invalidateIntrinsicContentSize];
    [self setNeedsLayout];
    [self layoutIfNeeded];
    
    NSLog(@"bubbleView.size %@, msgId = %llu", NSStringFromCGSize(bubbleView.bounds.size), message.msgId);
}

//视图自动布局(长度和宽度)
- (void)autolayout:(UIView*)bubbleView size:(CGSize)size
{
    NSArray* constraints = [bubbleView constraints];
    [constraints enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSLayoutConstraint* constraint = obj;
        NSLog(@"first item = %@(attr:%i),  second item = %@(attr:%i), constant = %f", ((NSObject*)constraint.firstItem).class, constraint.firstAttribute, ((NSObject*)constraint.secondItem).class, constraint.secondAttribute, constraint.constant);
        //宽度约束
        if(constraint.firstItem == bubbleView && constraint.secondItem == nil && constraint.firstAttribute == NSLayoutAttributeWidth) {
            NSLog(@"found the bubbleView's width constraint, constant = %f", constraint.constant);
            constraint.constant = size.width;
        }
        //高度约束
        if(constraint.firstItem == bubbleView && constraint.secondItem == nil && constraint.firstAttribute == NSLayoutAttributeHeight) {
            NSLog(@"found the bubbleView's height constraint, constant = %f", constraint.constant);
            constraint.constant = size.height;
        }
    }];

//    NSLog(@"want to set size %@", NSStringFromCGSize(size));
//    bubbleView.bounds = CGRectMake(0, 0, size.width, size.height);
//    [self.contentView setNeedsLayout];
//    [self.contentView layoutIfNeeded];
//    NSLog(@"set size result %@", NSStringFromCGSize(bubbleView.bounds.size));

//    NSLog(@"bubbleView.bounds %@", NSStringFromCGRect(bubbleView.bounds));
}

//创建视图
- (void)prepareView:(UIView*)bubbleView attributedString:(NSAttributedString*)attributedString fromSelf:(BOOL)fromSelf
{
    //背景图片
    UIImage *bubble = [UIImage imageNamed:fromSelf?@"SenderAppNodeBkg_HL":@"ReceiverTextNodeBkg"];
//	UIImage *bubble = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fromSelf?@"SenderAppNodeBkg_HL":@"ReceiverTextNodeBkg" ofType:@"png"]];
    
    //设置图片不拉伸边缘范围
    UIImageView *backgroundImageView = [[UIImageView alloc] initWithImage:[bubble stretchableImageWithLeftCapWidth:30 topCapHeight:30]];
    
    //创建帧管理器
    CTFramesetterRef ctFramesetter = CTFramesetterCreateWithAttributedString((__bridge CFMutableAttributedStringRef)attributedString);
    
    //计算内容渲染的宽度和高度
    //CGSize suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(ctFramesetter,CFRangeMake(0, 0), NULL, CGSizeMake(CONTENT_MAX_WIDTH, CONTENT_MAX_HEIGHT), NULL);
    CGSize suggestSize = [self suggestSizeFrameSizeWithFramesetter:ctFramesetter size:CGSizeMake(CONTENT_MAX_WIDTH, CONTENT_MAX_HEIGHT)];
    
    //信息内容视图
    ChatView* contentView = [[ChatView alloc] initWithCTFramesetterRef:ctFramesetter andFrame:CGRectMake(fromSelf?CONTENT_HORI_SAPCE:CONTENT_HORI_SAPCE+3, CONTENT_VERT_SAPCE, ceilf(suggestSize.width), ceilf(suggestSize.height))];
    NSLog(@"contentView %@", NSStringFromCGRect(contentView.frame));
    contentView.delegate = self;
    
    //contentView.bounds = UIEdgeInsetsInsetRect(contentView.bounds, UIEdgeInsetsMake(0.0, 0.0, 0.0, 0.0));
    contentView.backgroundColor = [UIColor clearColor];
    
    backgroundImageView.frame = CGRectMake(0.0f, 0.0f, contentView.frame.size.width + CONTENT_HORI_SAPCE*2, contentView.frame.size.height + CONTENT_VERT_SAPCE*2 + 10);
    NSLog(@"backgroundImageView %@", NSStringFromCGRect(backgroundImageView.frame));
    
//	if(fromSelf)
//		returnView.frame = CGRectMake(320-position-(bubbleText.frame.size.width+30.0f), 0.0f, bubbleText.frame.size.width+30.0f, bubbleText.frame.size.height+30.0f);
//	else
//		returnView.frame = CGRectMake(position, 0.0f, bubbleText.frame.size.width+30.0f, bubbleText.frame.size.height+30.0f);
    
	[bubbleView addSubview:backgroundImageView];
    [bubbleView addSubview:contentView];
    bubbleView.backgroundColor = [UIColor clearColor];
    
    [self autolayout:bubbleView size:backgroundImageView.bounds.size];
}

//- (CGSize)intrinsicContentSize
//{
//    return CGSizeMake(1, 1);
//}

////泡泡语音
//- (void)yuyinView:(NSInteger)logntime from:(BOOL)fromSelf  withPosition:(int)position withView:(UIView *)yuyinView{
//    
//    for (UIView *subView in yuyinView.subviews) {
//        [subView removeFromSuperview];
//    }
//    
//    //根据语音长度
//    int yuyinwidth = 66+fromSelf;
//    
//    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
//    button.tag = 250;
//    if(fromSelf)
//        yuyinView.frame =CGRectMake(320-position-yuyinwidth, 10, yuyinwidth, 54);
//	else
//		yuyinView.frame =CGRectMake(position, 10, yuyinwidth, 54);
//    
//    button.frame = CGRectMake(0, 0, yuyinwidth, 54);
//    [yuyinView addSubview:button];
//    
//    //image偏移量
//    UIEdgeInsets imageInsert;
//    imageInsert.top = -10;
//    imageInsert.left = fromSelf?button.frame.size.width/3:-button.frame.size.width/3;
//    button.imageEdgeInsets = imageInsert;
//    
//    [button setImage:[UIImage imageNamed:fromSelf?@"SenderVoiceNodePlaying":@"ReceiverVoiceNodePlaying"] forState:UIControlStateNormal];
//    UIImage *backgroundImage = [UIImage imageNamed:fromSelf?@"SenderVoiceNodeDownloading":@"ReceiverVoiceNodeDownloading"];
//    backgroundImage = [backgroundImage stretchableImageWithLeftCapWidth:20 topCapHeight:0];
//    [button setBackgroundImage:backgroundImage forState:UIControlStateNormal];
//    
//    UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(fromSelf?-30:button.frame.size.width, 0, 30, button.frame.size.height)];
//    label.text = [NSString stringWithFormat:@"%d''",logntime];
//    label.textColor = [UIColor grayColor];
//    label.font = [UIFont systemFontOfSize:13];
//    label.textAlignment = NSTextAlignmentCenter;
//    label.backgroundColor = [UIColor clearColor];
//    [button addSubview:label];
//    
//}

#pragma mark - ChatViewDelegate
- (void)chatImageClick:(ChatImage *)chatImage
{
    if ([self.delegate respondsToSelector:@selector(imageClick:)]) {
        [self.delegate imageClick:chatImage.image];
    }
}

@end
